home *** CD-ROM | disk | FTP | other *** search
/ World of Education / World of Education.iso / world_m / mercuryz.zip / X0.C < prev    next >
C/C++ Source or Header  |  1992-03-24  |  3KB  |  133 lines

  1.  
  2. /* X0.c
  3.  
  4. This is the startup module for external functions.
  5. Recompiling requires Borland C++ or Turbo C and Assembler.
  6.  
  7. There is an alternate startup module in this file for external
  8. functions which do not require DS=SS.  The math library, ld.lib,
  9. which has been provided, does not require DS=SS.  Programs built
  10. with this save some disk space.
  11.  
  12. Options.
  13.  
  14. You must set Opt=1 or Opt=2.
  15.  
  16. 1. External function sets up its own stack segment.  This allows
  17. you to guarantee enough stack space, but more importantly, it allows
  18. DS=SS which is what the compiler expects in tiny model.  Unfortunately,
  19. however, the floating point emulator doesn't work in a foreign stack
  20. segment.  Do not use this option unless you are using a math coprocessor.
  21.  
  22. 2. External function uses Mercury's stack segment.  This is more efficient,
  23. but requires you to write your function in tiny model without using DS=SS,
  24. which Borland C tiny model normally assumes.  Most simple functions in tiny
  25. model don't actually make use of DS=SS, but this option is dangerous unless
  26. you are familiar with the way Turbo C generates code.
  27.  
  28. bcc -c -mt! -w -ox01 -DOpt=1 -Z -O x0
  29. bcc -c -mt! -w -ox02 -DOpt=2 -Z -O x0
  30.  
  31. x01.obj uses stack swap
  32. x02.obj uses Mercury stack
  33.  
  34. See the examples, GCD.C and ASINH.C, for instructions on how to link.
  35. Using Option 1 requires linking with F87.OBJ.
  36.  
  37. If using Turbo, compile with "tcc -c -mt -w ...".
  38. */
  39.  
  40.  
  41. #pragma inline
  42.  
  43. /* TC is not too happy about this, but it does the right thing. */
  44. #pragma warn -asm
  45. asm DGROUP    group    _TEXT,_DATA,_BSS
  46. #pragma warn .asm
  47.  
  48. pascal xmain(double far *);
  49.  
  50. /*
  51. To handle tiny model properly, must have CS=DS=SS.
  52. Simple programs, eg not passing addresses of local variables, don't need SS.
  53.  
  54. */
  55.  
  56. #ifndef    Opt
  57. #error Must define Opt=1 or Opt=2.
  58. #endif
  59.  
  60. #if    Opt == 1
  61. #define    SwapSS    1
  62. #endif
  63.  
  64. #if    Opt == 2
  65. #define    SwapSS    0
  66. #endif
  67.  
  68. #if    !SwapSS
  69.  
  70. /* Opt = 2 */
  71.  
  72. static void far pascal start(double *a)
  73. {
  74.  
  75.     _ES = _SI = _DS;
  76.     _DS = _CS;
  77.  
  78.     xmain((double _es *) a);
  79.  
  80.     _DS = _SI;
  81.     return;
  82. }
  83.  
  84. #else
  85.  
  86. /* Opt = 1 */
  87.  
  88. /* make external, so user can set it? */
  89. #define StackWords    1000
  90. int stack[StackWords] = { 0 };
  91.  
  92. /*
  93. Must preserve bp, si, di, ds, ss.
  94. Called with ds = ss.
  95. */
  96.  
  97. static void far pascal start(double *a)
  98. {
  99.     _BX = (unsigned int) a;
  100. asm    mov    cx, sp
  101. asm    mov    dx, ss
  102.  
  103.     _AX = (unsigned int) (&stack[StackWords]);
  104.  
  105. /* switch to local stack */
  106. asm    push    cs
  107. asm    pop    ss
  108. asm    mov    sp, ax
  109.  
  110. /* save prior ss, sp */
  111. asm    push    dx
  112. asm    push    cx
  113.  
  114. /* set ds=cs */
  115. asm    push    cs
  116. asm    pop    ds
  117.  
  118. /* call xmain */
  119. asm    mov    es, dx
  120.     xmain((double _es *) _BX);
  121.  
  122. /* restore ss, sp, ds=ss */
  123. asm    pop    cx
  124. asm    pop    dx
  125. asm    mov    ss, dx
  126. asm    mov    sp, cx
  127. asm    mov    ds, dx
  128.  
  129.     return;
  130. }
  131.  
  132. #endif
  133.